From 9ab40284080aa6bc4a7a6c12c43e54c13d25e224 Mon Sep 17 00:00:00 2001 From: james_sherring Date: Sat, 6 Dec 2003 12:39:05 +0000 Subject: [PATCH] Support GPX /pushpin icon number --- st2gpx/src/ToDo.txt | 1 + st2gpx/src/debug.c | 3 +- st2gpx/src/gpx.h | 6 ++ st2gpx/src/history.txt | 4 +- st2gpx/src/ppinutil.c | 85 +++++++++++++++++ st2gpx/src/ppinutil.h | 46 ++++++++-- st2gpx/src/pushpins.cpp | 112 ++++++++++++++++++----- st2gpx/src/readgpx.c | 198 ++++++++++++++++++++++++++++++++++++++-- st2gpx/src/st2gpx.c | 36 ++++++-- st2gpx/src/st2gpx.dsp | 17 ---- st2gpx/src/st2gpx.h | 9 +- st2gpx/src/writegpx.c | 89 +++++++++++------- 12 files changed, 504 insertions(+), 102 deletions(-) diff --git a/st2gpx/src/ToDo.txt b/st2gpx/src/ToDo.txt index 5405585c3..c3ab5e37b 100644 --- a/st2gpx/src/ToDo.txt +++ b/st2gpx/src/ToDo.txt @@ -27,3 +27,4 @@ Still to test: * import to file with existing data * import to empty file * meaning of options etc for v4 files + diff --git a/st2gpx/src/debug.c b/st2gpx/src/debug.c index 675338d0b..62a11a5be 100644 --- a/st2gpx/src/debug.c +++ b/st2gpx/src/debug.c @@ -53,13 +53,14 @@ void debug_pause() void printbuf(char* buf, int len) { int i; + unsigned char * ubuf = (unsigned char *)buf; printf(" 0 1 2 3 4 5 6 7 8 9 A B C D E F\n"); printf(" -----------------------------------------------"); for(i=0; iNoteShort=NULL; nw->UdName=NULL; strcpy(nw->garmin_ident, " "); + nw->RenderData=0; + nw->RenderData2=0; + nw->url=NULL; + nw->urlname=NULL; return nw; } @@ -88,6 +92,8 @@ void pushpin_delete(struct pushpin * pp) return; free(pp->NoteShort); free(pp->UdName); + free(pp->url); + free(pp->urlname); free(pp); } @@ -288,3 +294,82 @@ struct pushpin_safelist * process_pushpin_file(char* ppin_in_file_name) return ppplist; } + +char std_udm1[6] = {18, 0, 0, 0, 0, 0}; +char std_udm2[1] = {1}; + +void explore_udm_data(struct pushpin_safelist * ppl) +{ + int i; + struct f_udm0_header * udm0_head=NULL; + struct f_udm0_header1 * udm0_head1=NULL; + struct f_udm0_ppin * udm0_ppin=NULL; + int expected_udm2_len=0; + + printf("Exploring UDM_Data from UserData\n"); + + // check UDM_Data[1] + if(ppl->UDM_Data_length[1] != 6) + printf("Unexpcted UDM_Data[1] length = %d, expected length 6\n", + ppl->UDM_Data_length[1]); + else + for(i=0; i<6; i++) + if(ppl->UDM_Data[1][i] != std_udm1[i]) + printf("UDM_Data[1][%d]=%#x, normally expect value %#x\n", + i, + (unsigned char)(ppl->UDM_Data[1][i]), + (unsigned char)(std_udm1[i])); + + // check UDM_Data[2] + if(ppl->UDM_Data_length[2] != 1) + printf("Unexpcted UDM_Data[2] length = %d, expected length 1\n", + ppl->UDM_Data_length[2]); + else + if(ppl->UDM_Data[2][0] != std_udm2[0]) + printf("UDM_Data[2][0]=%#x, normally expect value %#x\n", + (unsigned char)ppl->UDM_Data[2][0], + (unsigned char)(std_udm2[0])); + + // check UDM_Data[0] + + if (ppl->UDM_Data_length[0] < 14) + { + printf("UDM_Data[0] is too small to have a valid header\n"); + return; + } + + udm0_head = (struct f_udm0_header *)(ppl->UDM_Data[0]); + printf("There are %d highlighted pushpins\n", udm0_head->c_highlight_recs); + // list the highlighted udids? Nah. + + if(udm0_head->sunkn != 0x8001) + { + printf("Unexpected f_udm0_header:\n"); + printbuf(ppl->UDM_Data[0], sizeof(struct f_udm0_header)); + } + + udm0_head1 = (struct f_udm0_header1*) + (ppl->UDM_Data[0] + sizeof(struct f_udm0_header) + + 4*(udm0_head->c_highlight_recs)); + + if( udm0_head1->iunkn != 0) + printf("Unexpected f_udm0_header1->iunkn=%#x:\n",udm0_head1->iunkn); + + expected_udm2_len = (14 + 4*(udm0_head->c_highlight_recs) + + 6*(udm0_head1->c_format_records)); + if(ppl->UDM_Data_length[0] != expected_udm2_len) + printf("Unexpcted UDM_Data[0] length = %d, expected length %d for %d indicated format_records\n", + ppl->UDM_Data_length[0], expected_udm2_len, udm0_head1->c_format_records); + else + { + udm0_ppin = (struct f_udm0_ppin *)(ppl->UDM_Data[0] + 14 + 4*(udm0_head->c_highlight_recs) ); + // size has already been verified as (14 + 6 * udm0_head->c_format_records) + for(i=0; i<(udm0_head1->c_format_records); i++) + printf("udm0 ppin_rec[%d] has udid=%d, format=%#x, zorder=%d\n", + i, + udm0_ppin[i].ppin_udid, + udm0_ppin[i].format, + udm0_ppin[i].zorder); + } + +} \ No newline at end of file diff --git a/st2gpx/src/ppinutil.h b/st2gpx/src/ppinutil.h index cade80e3c..9a6483071 100644 --- a/st2gpx/src/ppinutil.h +++ b/st2gpx/src/ppinutil.h @@ -28,6 +28,33 @@ extern "C" { #endif +// The structures in UserData/UDM_Data for UDMId=0 +typedef struct f_udm0_header +{ + unsigned short int sunkn; // normally 0x8001 + int c_highlight_recs; +} tag_f_udm0_header; +// then c_highlight_recs ints with udid of highlighted ppin +typedef struct f_udm0_header1 +{ + int iunkn; // normally 0, probably indicates some array length to mess everything up + int c_format_records; +} tag_f_udm0_header1; +// then c_format_records of these: +typedef struct f_udm0_ppin +{ + int ppin_udid; + // 1 = show name + info + // (no record if name not shown?) + // 3 = show name + // 4 = upper left + // 8 = upper right + // 12 = lower left + // 16 = lower right + unsigned char format; + unsigned char zorder; +} tag_f_udm0_ppin; + typedef struct pushpin_safelist { struct pushpin ** pushpin_list; @@ -55,9 +82,15 @@ typedef struct pushpin int SetId; long Grid; long Precision; + int RenderData; + // only in mappoint? + int RenderData2; // dword RenderData; -// byte MatchId; -// long MOBBId; + // 1 = by hand + // 2 = from file? + // 4 = not matched? + short int MatchId; + long MOBBId; // long SourceUdId; // bool IsTerritory; // @@ -75,12 +108,9 @@ typedef struct pushpin // shouldn't include these 3 here because they are not part of the native pushpin definition double lat; double lon; - // 1 = by hand - // 2 = from file? - // 4 = not matched? - short int MatchId; - long MOBBId; char garmin_ident[7]; + char* url; + char* urlname; } tag_pushpin; @@ -123,6 +153,8 @@ struct pushpin_safelist * process_pushpin_file(char* ppin_in_file_name); struct point grid2latlon(long grid, long precision); struct grid_point latlon2grid(double lat, double lon); +void explore_udm_data(struct pushpin_safelist * ppl); + #ifdef __cplusplus } #endif diff --git a/st2gpx/src/pushpins.cpp b/st2gpx/src/pushpins.cpp index 7bc4f7b30..77ff59a62 100644 --- a/st2gpx/src/pushpins.cpp +++ b/st2gpx/src/pushpins.cpp @@ -105,7 +105,7 @@ VARIANT val2variant(unsigned short fieldtype, void* stor_var) return vt_val; }; -void variant2val(VARIANT vt_val, unsigned short fieldtype, void* stor_var) +void variant2val(VARIANT vt_val, unsigned short fieldtype, void* stor_var, int expected_buf_length) { char* shortstr=NULL; long lbound; @@ -114,7 +114,8 @@ void variant2val(VARIANT vt_val, unsigned short fieldtype, void* stor_var) // should be a short? char array_val=0; - if ((vt_val.vt == fieldtype) || ( (fieldtype==VT_BSTR) && (vt_val.vt==VT_NULL))) + if ((vt_val.vt == fieldtype) || ( (fieldtype==VT_BSTR) && (vt_val.vt==VT_NULL)) + || ( (fieldtype==(VT_ARRAY | VT_UI1)) && (vt_val.vt==VT_NULL)) ) { switch (vt_val.vt) { @@ -134,6 +135,7 @@ void variant2val(VARIANT vt_val, unsigned short fieldtype, void* stor_var) break; case VT_NULL: + // FIXME should return NULL here and hande the nulls elsewhere // expected string, this is null // so return empty string shortstr = (char*)xmalloc(1); @@ -147,14 +149,23 @@ void variant2val(VARIANT vt_val, unsigned short fieldtype, void* stor_var) { printf("got safe array of short ints, with %d dimensions and bounds %d:%d\n", SafeArrayGetDim(vt_val.parray), lbound, ubound); - printf("Sadly, I was expecting 1 dimention and lower bound of zero, so I will ignore this array.\n"); + printf("Sadly, I was expecting 1 dimension and lower bound of zero, so I will ignore this array.\n"); break; } + + if (ubound+1 != expected_buf_length) + { + printf("Error reading VT_ARRAY: expected length %d but array has length %d\n", + expected_buf_length, ubound); + //return; + } for(elmt=lbound; elmtpushpin_list = (struct pushpin **)xmalloc(ppin_list_alloc_size*sizeof(struct pushpin *)); if (opts.st_version_num<9) - ppin_sql = "SELECT UD_Secondary.UdId, UD_Secondary.UdName, UD_Secondary.NoteShort, UD_Secondary.NoteLong, UD_Main.Grid, UD_Main.Precision, UD_Main.MatchId, UD_Main.MOBBId FROM UD_Main INNER JOIN UD_Secondary ON UD_Main.UdId = UD_Secondary.UdId"; + ppin_sql = "SELECT UD_Secondary.UdId, UD_Secondary.UdName, UD_Secondary.NoteShort, UD_Secondary.NoteLong, UD_Main.Grid, UD_Main.Precision, UD_Main.RenderData, UD_Main.MatchId, UD_Main.MOBBId FROM UD_Main INNER JOIN UD_Secondary ON UD_Main.UdId = UD_Secondary.UdId"; else - ppin_sql = "SELECT UdId, UdName, NoteShort, NoteLong, Grid, Precision, MatchId, MOBBId FROM UD_Main"; + ppin_sql = "SELECT UdId, UdName, NoteShort, NoteLong, Grid, Precision, RenderData, MatchId, MOBBId FROM UD_Main"; try { @@ -219,13 +233,44 @@ EXTERN_C struct pushpin_safelist * read_pushpins(char* ppin_file_name) { ppin = pushpin_new(); - variant2val(rs->Fields->GetItem("UdId")->Value, VT_I4, &(ppin->UdId)); - variant2val(rs->Fields->GetItem("UdName")->Value, VT_BSTR,&(ppin->UdName)); - variant2val(rs->Fields->GetItem("Grid")->Value, VT_I4, &(ppin->Grid)); - variant2val(rs->Fields->GetItem("Precision")->Value,VT_I4, &(ppin->Precision)); - variant2val(rs->Fields->GetItem("NoteShort")->Value,VT_BSTR,&(ppin->NoteShort)); - variant2val(rs->Fields->GetItem("MatchId")->Value, VT_I2, &(ppin->MatchId)); - variant2val(rs->Fields->GetItem("MOBBId")->Value, VT_I4, &(ppin->MOBBId)); + variant2val(rs->Fields->GetItem("UdId")->Value, VT_I4, &(ppin->UdId), 0); + variant2val(rs->Fields->GetItem("UdName")->Value, VT_BSTR,&(ppin->UdName), 0); + variant2val(rs->Fields->GetItem("Grid")->Value, VT_I4, &(ppin->Grid), 0); + variant2val(rs->Fields->GetItem("Precision")->Value,VT_I4, &(ppin->Precision), 0); + variant2val(rs->Fields->GetItem("NoteShort")->Value,VT_BSTR,&(ppin->NoteShort), 0); + + RenderData_len = rs->Fields->GetItem("RenderData")->ActualSize; + val_type = rs->Fields->GetItem("RenderData")->Value.vt; + if(val_type!=VT_NULL) + { + if (RenderData_len==4) + { + variant2val(rs->Fields->GetItem("RenderData")->Value,(VT_ARRAY | VT_UI1), RenderData_buf, RenderData_len); + ppin->RenderData = *(int*)RenderData_buf; + //printf("got pushpin symbol %#x=%d\n", ppin->RenderData, ppin->RenderData); + } + else if (RenderData_len==8) + { + variant2val(rs->Fields->GetItem("RenderData")->Value,(VT_ARRAY | VT_UI1), RenderData_buf, RenderData_len); + ppin->RenderData = *(int*)RenderData_buf; + //printf("got pushpin symbol %#x=%d\n", ppin->RenderData, ppin->RenderData); + ppin->RenderData2 = *(int*)(RenderData_buf+4); + if(ppin->RenderData2 != 0) + { + printf("got pushpin symbol %#x=%d\n", ppin->RenderData, ppin->RenderData); + printf("Got pushpin symbol part2 %#x=%d\n", ppin->RenderData2, ppin->RenderData2); + } + } + else + { + printf("Unexpected RenderData_len=%d\n", RenderData_len); + variant2val(rs->Fields->GetItem("RenderData")->Value,(VT_ARRAY | VT_UI1), RenderData_buf, RenderData_len); + printbuf(RenderData_buf, RenderData_len); + } + } + + variant2val(rs->Fields->GetItem("MatchId")->Value, VT_I2, &(ppin->MatchId), 0); + variant2val(rs->Fields->GetItem("MOBBId")->Value, VT_I4, &(ppin->MOBBId), 0); str2ascii(ppin->UdName); str2ascii(ppin->NoteShort); @@ -256,12 +301,14 @@ EXTERN_C struct pushpin_safelist * read_pushpins(char* ppin_file_name) hr = rs->MoveNext(); } hr = rs->Close(); + ppplist->num_pushpins=ppinnum; // ************* // read UDM_Data // ************* - if (opts.explore_flag) + // always read udm data now + //if (opts.explore_flag) { UDM_sql = "Select UdmDataId, UdmData from UDM_Data"; @@ -273,7 +320,7 @@ EXTERN_C struct pushpin_safelist * read_pushpins(char* ppin_file_name) while ((rs->adoEOF == FALSE)) { - variant2val(rs->Fields->GetItem("UdmDataId")->Value, VT_I4, &UdmDataId); + variant2val(rs->Fields->GetItem("UdmDataId")->Value, VT_I4, &UdmDataId, 0); if ( (UdmDataId<0) || (UdmDataId>3) ) { printf("*** Unexpected UdmDataId=%d\n", UdmDataId); @@ -282,15 +329,23 @@ EXTERN_C struct pushpin_safelist * read_pushpins(char* ppin_file_name) ppplist->UDM_Data_length[UdmDataId] = rs->Fields->GetItem("UdmData")->ActualSize; ppplist->UDM_Data[UdmDataId]=(char*)xmalloc(ppplist->UDM_Data_length[UdmDataId]); - variant2val(rs->Fields->GetItem("UdmData")->Value, VT_ARRAY | VT_UI1, ppplist->UDM_Data[UdmDataId]); + variant2val(rs->Fields->GetItem("UdmData")->Value, VT_ARRAY | VT_UI1, ppplist->UDM_Data[UdmDataId], ppplist->UDM_Data_length[UdmDataId] ); printf("In UDM_Data table, for UdId=%d got %d bytes of data\n", UdmDataId, ppplist->UDM_Data_length[UdmDataId]); - printbuf(ppplist->UDM_Data[UdmDataId], ppplist->UDM_Data_length[UdmDataId]); + + if (opts.explore_flag) + { + printbuf(ppplist->UDM_Data[UdmDataId], ppplist->UDM_Data_length[UdmDataId]); + } hr = rs->MoveNext(); } hr = rs->Close(); + + if (opts.explore_flag) + explore_udm_data(ppplist); + } rs = NULL; @@ -311,9 +366,8 @@ EXTERN_C struct pushpin_safelist * read_pushpins(char* ppin_file_name) } if (opts.verbose_flag > 1) - printf("Read %d pushpins from %s.\n", ppinnum, ppin_file_name); + printf("Read %d pushpins from %s.\n", ppplist->num_pushpins, ppin_file_name); - ppplist->num_pushpins=ppinnum; return ppplist; } @@ -355,9 +409,9 @@ EXTERN_C void write_pushpins_from_gpx(char* ppin_file_name, ADODB::adLockOptimistic, -1 ); - variant2val(rs->Fields->GetItem("DbVersion")->Value, VT_I2, &DbVersion); - variant2val(rs->Fields->GetItem("LastSetId")->Value, VT_I4, &LastSetId); - variant2val(rs->Fields->GetItem("LastUserDataId")->Value, VT_I4, &LastUserDataId); + variant2val(rs->Fields->GetItem("DbVersion")->Value, VT_I2, &DbVersion, 0); + variant2val(rs->Fields->GetItem("LastSetId")->Value, VT_I4, &LastSetId, 0); + variant2val(rs->Fields->GetItem("LastUserDataId")->Value, VT_I4, &LastUserDataId, 0); printf("Got DbVersion=%d, LastSetId=%d and LastUserDataId=%d\n", DbVersion, LastSetId, LastUserDataId); @@ -386,7 +440,7 @@ EXTERN_C void write_pushpins_from_gpx(char* ppin_file_name, if (opts.st_version_num<9) { - sql = "Select UdId, SetId, Grid, Precision, MatchId, MOBBId, SourceUdId from UD_Main"; + sql = "Select UdId, SetId, Grid, Precision, RenderData, MatchId, MOBBId, SourceUdId from UD_Main"; sql2 = "Select UdId, NoteTypeId, GeocodeHierarchy, GeocodeContext, UdName, NoteShort, NoteLong from UD_Secondary"; hr = rs->Open(sql, cnstr, @@ -402,7 +456,7 @@ EXTERN_C void write_pushpins_from_gpx(char* ppin_file_name, } else { - sql = "Select UdId, SetId, Grid, Precision, MatchId, MOBBId, SourceUdId, NoteTypeId, GeocodeHierarchy, GeocodeContext, UdName, NoteShort, NoteLong from UD_Main"; + sql = "Select UdId, SetId, Grid, Precision, RenderData, MatchId, MOBBId, SourceUdId, NoteTypeId, GeocodeHierarchy, GeocodeContext, UdName, NoteShort, NoteLong from UD_Main"; // maybe we have to do this later, when rs is set? hr = rs->Open(sql, cnstr, @@ -445,6 +499,14 @@ EXTERN_C void write_pushpins_from_gpx(char* ppin_file_name, rs->Fields->GetItem("Grid" )->Value = val2variant(VT_I4, &(gridpt.grid)); rs->Fields->GetItem("Precision" )->Value = val2variant(VT_I4, &(gridpt.precision)); rs->Fields->GetItem("MatchId" )->Value = val2variant(VT_I2, &sitwo); + // This is stored in the DB as binary type, + // but hopefully it should be ok to write as int. + // FIXME - Potential problem: + // This field has longer maximum width in newer MAP versions. + // Width 32 (AR2001), 64 (MP2002), 128 (AR2003) + + if(gpt->symbol != 0) + rs->Fields->GetItem("RenderData" )->Value = val2variant(VT_I4, &(gpt->symbol)); rs->Fields->GetItem("MOBBId" )->Value = val2variant(VT_I4, &lzero); rs->Fields->GetItem("SourceUdId")->Value = val2variant(VT_I4, &lzero); diff --git a/st2gpx/src/readgpx.c b/st2gpx/src/readgpx.c index c6e0ccf7d..a6ea04453 100644 --- a/st2gpx/src/readgpx.c +++ b/st2gpx/src/readgpx.c @@ -55,7 +55,11 @@ char * gpx_elem_name[] = "trkpt", "name", "desc", - "src" + "src", + "sym", + "type", + "url", + "urlname" }; struct gpxpt * gpxpt_new() @@ -67,6 +71,9 @@ struct gpxpt * gpxpt_new() nw->lon=0; nw->elevation=0; nw->use_elevation=0; + nw->symbol=0; + nw->url=NULL; + nw->urlname=NULL; return nw; } @@ -76,20 +83,23 @@ void gpxpt_delete(struct gpxpt * pt) return; free(pt->name); free(pt->desc); + free(pt->url); + free(pt->urlname); free(pt); } struct gpxpt * gpxpt_copy(struct gpxpt * otherpt) { struct gpxpt * nw = (struct gpxpt *)xmalloc(sizeof(struct gpxpt)); - nw->name=xmalloc(strlen(otherpt->name)+1); - strcpy(nw->name, otherpt->name); - nw->desc=xmalloc(strlen(otherpt->desc)+1); - strcpy(nw->desc, otherpt->desc); + nw->name = _strdup(otherpt->name); + nw->desc = _strdup(otherpt->desc); nw->lat=otherpt->lat; nw->lon=otherpt->lon; nw->elevation=otherpt->elevation; nw->use_elevation=otherpt->use_elevation; + nw->symbol = otherpt->symbol; + nw->url = _strdup(otherpt->url); + nw->urlname = _strdup(otherpt->urlname); return nw; } @@ -486,7 +496,6 @@ void enddesc(void *userData, const char *name) desc[cdata_length]=0; cdata=NULL; cdata_length=0; - str2ascii(desc); switch (current_main_element) { case GPX_ELEM_TYPE_WPT: @@ -521,7 +530,169 @@ void endsrc(void *userData, const char *name) { } -#define GPX_NUM_ELEM_HANDLERS 10 +void startsym(void *userData, const char *name, const char **atts) +{ +} + +void endsym(void *userData, const char *name) +{ + struct gpx_data * dat = (struct gpx_data *)userData; + char* sym_str = xrealloc(cdata, cdata_length+1); + int sym_num=0; + int read; + + sym_str[cdata_length]=0; + cdata=NULL; + cdata_length=0; + + + // We need to convert the name of the symbol sym_str from GPX + // into a numeric symbol number for MS Map. + // For now we just accept MS Map Symbol n + +/* if (strncmp(sym_str, "MS Map Symbol", 13)!=0) + { + free(sym_str); + return; + } +*/ + read=sscanf(sym_str, "MS Map Symbol %d", &sym_num); + + if( (read==1) && (sym_num>0) ) + printf("Translated symbol name %s as symbol number %d\n", sym_str, sym_num); + else + { + printf("Couldn't translate symbol name %s to a symbol number\n", sym_str); + free(sym_str); + return; + } + + switch (current_main_element) + { + case GPX_ELEM_TYPE_WPT: + // We may have already set the symbol from , + // which over-rides the symbol. + // Fixme this override should eb an option, not the default. + if(dat->wpt_list[dat->wpt_list_count-1]->symbol == 0) + dat->wpt_list[dat->wpt_list_count-1]->symbol=sym_num; + break; + case GPX_ELEM_TYPE_RTE: + case GPX_ELEM_TYPE_RTEPT: + case GPX_ELEM_TYPE_TRK: + case GPX_ELEM_TYPE_TRKSEG: + case GPX_ELEM_TYPE_TRKPT: + default: + break; + } + + free(sym_str); +} + +void starttype(void *userData, const char *name, const char **atts) +{ +} + +void endtype(void *userData, const char *name) +{ + struct gpx_data * dat = (struct gpx_data *)userData; + char* type_str = xrealloc(cdata, cdata_length+1); + int sym_num=0; + + type_str[cdata_length]=0; + cdata=NULL; + cdata_length=0; + + if(strcmp(type_str, "Geocache|Virtual Cache")==0) + sym_num=68; // balloon + else if(strcmp(type_str, "Geocache|Traditional Cache")==0) + sym_num=55; // small purple or green triange + else if(strcmp(type_str, "Geocache|Multi-Cache")==0) + sym_num=107; // three flags + //sym_num=132; // traffic-light + else if(strcmp(type_str, "Geocache|Unknown Cache")==0) + sym_num=254; // question-mark + else if(strcmp(type_str, "Geocache|Micro Cache")==0) + sym_num=65; + + switch (current_main_element) + { + case GPX_ELEM_TYPE_WPT: + if(sym_num != 0) + dat->wpt_list[dat->wpt_list_count-1]->symbol=sym_num; + break; + case GPX_ELEM_TYPE_RTE: + case GPX_ELEM_TYPE_RTEPT: + case GPX_ELEM_TYPE_TRK: + case GPX_ELEM_TYPE_TRKSEG: + case GPX_ELEM_TYPE_TRKPT: + default: + break; + } + + free(type_str); +} + +void starturl(void *userData, const char *name, const char **atts) +{ +} + +void endurl(void *userData, const char *name) +{ + struct gpx_data * dat = (struct gpx_data *)userData; + char* url_str = xrealloc(cdata, cdata_length+1); + + url_str[cdata_length]=0; + cdata=NULL; + cdata_length=0; + + switch (current_main_element) + { + case GPX_ELEM_TYPE_WPT: + dat->wpt_list[dat->wpt_list_count-1]->url=url_str; + break; + case GPX_ELEM_TYPE_RTE: + case GPX_ELEM_TYPE_RTEPT: + case GPX_ELEM_TYPE_TRK: + case GPX_ELEM_TYPE_TRKSEG: + case GPX_ELEM_TYPE_TRKPT: + default: + break; + free(url_str); + } + +} + +void starturlname(void *userData, const char *name, const char **atts) +{ +} + +void endurlname(void *userData, const char *name) +{ + struct gpx_data * dat = (struct gpx_data *)userData; + char* url_str = xrealloc(cdata, cdata_length+1); + + url_str[cdata_length]=0; + cdata=NULL; + cdata_length=0; + + switch (current_main_element) + { + case GPX_ELEM_TYPE_WPT: + dat->wpt_list[dat->wpt_list_count-1]->urlname=url_str; + break; + case GPX_ELEM_TYPE_RTE: + case GPX_ELEM_TYPE_RTEPT: + case GPX_ELEM_TYPE_TRK: + case GPX_ELEM_TYPE_TRKSEG: + case GPX_ELEM_TYPE_TRKPT: + default: + break; + free(url_str); + } + +} + +#define GPX_NUM_ELEM_HANDLERS 14 gpx_elm_start_handler gpx_start_elm_handler[] = { @@ -534,7 +705,11 @@ gpx_elm_start_handler gpx_start_elm_handler[] = &starttrkpt, &startname, &startdesc, - &startsrc + &startsrc, + &startsym, + &starttype, + &starturl, + &starturlname }; gpx_elm_end_handler gpx_end_elm_handler[] = @@ -548,10 +723,13 @@ gpx_elm_end_handler gpx_end_elm_handler[] = &endtrkpt, &endname, &enddesc, - &endsrc + &endsrc, + &endsym, + &endtype, + &endurl, + &endurlname }; - int get_gpx_type_ndx(const char* type_name) { int i; diff --git a/st2gpx/src/st2gpx.c b/st2gpx/src/st2gpx.c index 864980ed8..0fc1d49d5 100644 --- a/st2gpx/src/st2gpx.c +++ b/st2gpx/src/st2gpx.c @@ -92,8 +92,13 @@ void * xrealloc(void* ptr, size_t size) char * str2ascii(char* str) { int i; - int len=strlen(str); + int len; unsigned char * ustr = (unsigned char*)str; + + if(str==NULL) + return str; + + len=strlen(str); for(i=0; i127) || (ustr[i]==0x1c) ) @@ -107,11 +112,30 @@ char * str2ascii(char* str) char * strappend(char* str1, char* str2) // create a new string { - int len1=strlen(str1); - int len2=strlen(str2); - char* nw = (char*)xmalloc(len1 + len2 +1); - strcpy(nw, str1); - strcpy(nw+len1, str2); + int len1; + int len2; + char* nw; + + if (str1==NULL) + len1=0; + else + len1=strlen(str1); + + if (str2==NULL) + len2=0; + else + len2=strlen(str2); + + nw = (char*)xmalloc(len1 + len2 +1); + + if (str1 != NULL) + strcpy(nw, str1); + if (str2 != NULL) + strcpy(nw+len1, str2); + + //just in case len1 + len2 =0 + nw[len1 + len2]=0; + return nw; } diff --git a/st2gpx/src/st2gpx.dsp b/st2gpx/src/st2gpx.dsp index df25be3bc..d47124a70 100644 --- a/st2gpx/src/st2gpx.dsp +++ b/st2gpx/src/st2gpx.dsp @@ -90,15 +90,6 @@ LINK32=link.exe # Begin Source File SOURCE=.\annotations.c - -!IF "$(CFG)" == "st2gpx - Win32 Release" - -!ELSEIF "$(CFG)" == "st2gpx - Win32 Debug" - -# SUBTRACT CPP /FA - -!ENDIF - # End Source File # Begin Source File @@ -223,14 +214,6 @@ SOURCE=.\history.txt # End Source File # Begin Source File -SOURCE=.\msado15.tlh -# End Source File -# Begin Source File - -SOURCE=.\msado15.tli -# End Source File -# Begin Source File - SOURCE=.\ToDo.txt # End Source File # End Target diff --git a/st2gpx/src/st2gpx.h b/st2gpx/src/st2gpx.h index 3738383de..670e3e1a3 100644 --- a/st2gpx/src/st2gpx.h +++ b/st2gpx/src/st2gpx.h @@ -28,10 +28,12 @@ extern "C" { #endif -//#define MEMCHK -//#define DEBUG_STDOUT #ifdef _DEBUG + +#define MEMCHK +#define DEBUG_STDOUT + #define _CRTDBG_MAP_ALLOC #define SET_CRT_DEBUG_FIELD(a) _CrtSetDbgFlag((a) | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG)) #define CLEAR_CRT_DEBUG_FIELD(a) _CrtSetDbgFlag(~(a) & _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG)) @@ -98,7 +100,8 @@ extern struct contents; extern struct st2gpx_options opts; void * xmalloc(size_t size); void * xrealloc(void* ptr, size_t size); -char * str2ascii(char* str); +char * str2ascii(char* str); +char * strappend(char* str1, char* str2); int readbytes(FILE* file, char* buf, int bytes2read); //nannol.c struct annotations * merge_gpx_annot(struct annotations * annots, struct gpx_data* all_gpx); diff --git a/st2gpx/src/writegpx.c b/st2gpx/src/writegpx.c index b61d88aa6..b0bd690bf 100644 --- a/st2gpx/src/writegpx.c +++ b/st2gpx/src/writegpx.c @@ -86,9 +86,8 @@ void gpx_write_file_trailer(FILE* gpx_out_file) } } -void gpx_write_point(FILE* gpx_out_file, struct gpxpt * pt, int pt_type, char* opt_elms) -// FIXEM do from pt, not from opt_elms -// FIXME same for other atts defined in gpxpt +void gpx_write_point(FILE* gpx_out_file, struct gpxpt * pt, int pt_type) +// FIXME write other atts defined in gpxpt { if (gpx_out_file!=NULL) { @@ -96,17 +95,28 @@ void gpx_write_point(FILE* gpx_out_file, struct gpxpt * pt, int pt_type, char* o fprintf(gpx_out_file, "\t\t"); else if (pt_type == GPX_RTEPT) fprintf(gpx_out_file, "\t"); - fprintf(gpx_out_file, "\t<%s lat=\"%f\" lon=\"%f\">%s\n", - gpxptypelabel[pt_type], pt->lat, pt->lon, - opt_elms, gpxptypelabel[pt_type]); + fprintf(gpx_out_file, "\t<%s lat=\"%f\" lon=\"%f\">", + gpxptypelabel[pt_type], pt->lat, pt->lon); + if( (pt->name != NULL) && (strlen(pt->name)>0) ) + fprintf(gpx_out_file, "", pt->name); + if( (pt->desc != NULL) && (strlen(pt->desc)>0) ) + fprintf(gpx_out_file, "", pt->desc); + // FIXME do some translation here? + if(pt->symbol != 0) + fprintf(gpx_out_file, "MS Map Symbol %d", pt->symbol); + if( (pt->url != NULL) && (strlen(pt->url)>0) ) + fprintf(gpx_out_file, "", pt->url); + if( (pt->urlname != NULL) && (strlen(pt->urlname)>0) ) + fprintf(gpx_out_file, "", pt->urlname); + fprintf(gpx_out_file, "\n", gpxptypelabel[pt_type]); } } void gpx_write_jour_point(FILE* gpx_out_file, struct journey * jour, struct jour_rtept * wpt) { struct gpxpt * pt = gpxpt_new(); - char* opt_elms; - int optlen; +// char* opt_elms; +// int optlen; struct f_jour_pt_head * f_wpt_head; if (gpx_out_file==NULL) @@ -118,28 +128,31 @@ void gpx_write_jour_point(FILE* gpx_out_file, struct journey * jour, struct jour f_wpt_head = (struct f_jour_pt_head *)(jour->buf + (wpt->pthead_os)); pt->lat=scaled2deg(f_wpt_head->scaled_lat); pt->lon=scaled2deg(f_wpt_head->scaled_lon); - optlen = f_wpt_head->cbtext1 + 60; - opt_elms = (char*)xmalloc(optlen); +// optlen = f_wpt_head->cbtext1 + 60; +// opt_elms = (char*)xmalloc(optlen); //FIXME use str2ascii?? - sprintf(opt_elms, "", wpt->text1); +// sprintf(opt_elms, "", wpt->text1); + pt->name=_strdup(wpt->text1); } else { - optlen = strlen(wpt->pushpin->UdName) + strlen(wpt->pushpin->NoteShort) + 60; - opt_elms = (char*)xmalloc(optlen); +// optlen = strlen(wpt->pushpin->UdName) + strlen(wpt->pushpin->NoteShort) + 60; +// opt_elms = (char*)xmalloc(optlen); - sprintf(opt_elms, "", - wpt->pushpin->UdName, wpt->pushpin->NoteShort); +// sprintf(opt_elms, "", +// wpt->pushpin->UdName, wpt->pushpin->NoteShort); + pt->name=_strdup(wpt->text1); + pt->desc=_strdup(wpt->pushpin->NoteShort); pt->lat = wpt->pushpin->lat; pt->lon = wpt->pushpin->lon; } - gpx_write_point(gpx_out_file, pt, GPX_RTEPT, opt_elms); + gpx_write_point(gpx_out_file, pt, GPX_RTEPT); gpxpt_delete(pt); - free(opt_elms); +// free(opt_elms); } void gpx_write_jour_header(FILE* gpx_out_file) @@ -176,8 +189,8 @@ void gpx_write_pushpinlist (FILE* gpx_out_file, struct pushpin_safelist *ppplist { int i; struct gpxpt * pt=NULL; - char* opt_elms; - int optlen; +// char* opt_elms; +// int optlen; if ((gpx_out_file==NULL) || (ppplist==NULL)) return; @@ -191,28 +204,37 @@ void gpx_write_pushpinlist (FILE* gpx_out_file, struct pushpin_safelist *ppplist if (ppplist->pushpin_list[i]==NULL) break; - optlen = strlen(ppplist->pushpin_list[i]->UdName) - + strlen(ppplist->pushpin_list[i]->NoteShort) + 60; - opt_elms = (char*)xmalloc(optlen); +// optlen = strlen(ppplist->pushpin_list[i]->UdName) +// + strlen(ppplist->pushpin_list[i]->NoteShort) + 60; +// opt_elms = (char*)xmalloc(optlen); - sprintf(opt_elms, "", - ppplist->pushpin_list[i]->UdName, ppplist->pushpin_list[i]->NoteShort); +// sprintf(opt_elms, "", +// ppplist->pushpin_list[i]->UdName, ppplist->pushpin_list[i]->NoteShort); + + pt->name = _strdup(ppplist->pushpin_list[i]->UdName); + pt->desc = _strdup(ppplist->pushpin_list[i]->NoteShort); pt->lat = ppplist->pushpin_list[i]->lat; pt->lon = ppplist->pushpin_list[i]->lon; - - gpx_write_point(gpx_out_file, pt, GPX_WPT, opt_elms); - free(opt_elms); + // FIXEM some translation is needed here + pt->symbol = ppplist->pushpin_list[i]->RenderData; + + gpx_write_point(gpx_out_file, pt, GPX_WPT); +// free(opt_elms); + free(pt->name); + pt->name=NULL; + free(pt->desc); + pt->desc=NULL; } fprintf(gpx_out_file, "\n"); gpxpt_delete(pt); } -void gpx_write_annot_rec(FILE* gpx_out_file, const struct annot_rec * rec) +void gpx_write_annot_rec(FILE* gpx_out_file, struct annot_rec * rec) { int pt_type; int p; - char opt_elms[200]; +// char opt_elms[200]; struct gpxpt * pt; if ( (gpx_out_file==NULL) || (rec==NULL) ) @@ -257,6 +279,7 @@ void gpx_write_annot_rec(FILE* gpx_out_file, const struct annot_rec * rec) for (p=0; p < rec->line_points; p++) { pt=gpx_get_point(rec->buf + rec->line_offset + 12*p); + pt->name=(char*)xmalloc(7); if(pt==NULL) { printf("got null pt #%p in annotation %d, skipping more points in this annotation\n", @@ -264,12 +287,14 @@ void gpx_write_annot_rec(FILE* gpx_out_file, const struct annot_rec * rec) break; } if(opts.use_gpx_route) - sprintf(opt_elms, "rp%04d", p); + sprintf(pt->name, "rp%04d", p); + //sprintf(opt_elms, "rp%04d", p); else // we need to include a name for trackpoints // for them to be recognised by easygps. - sprintf(opt_elms, "tp%04d", p); - gpx_write_point(gpx_out_file, pt, pt_type, opt_elms); + sprintf(pt->name, "tp%04d", p); + //sprintf(opt_elms, "tp%04d", p); + gpx_write_point(gpx_out_file, pt, pt_type); gpxpt_delete(pt); } -- 2.30.2